package com.whfc.fuum.service.impl;

import com.whfc.common.enums.SysRulePlatform;
import com.whfc.common.enums.SysUserType;
import com.whfc.common.exception.BizException;
import com.whfc.common.result.ResultEnum;
import com.whfc.fuum.dao.*;
import com.whfc.fuum.dto.SysRoleDTO;
import com.whfc.fuum.dto.SysRoleDetailDTO;
import com.whfc.fuum.dto.SysRuleDTO;
import com.whfc.fuum.dto.SysUserDTO;
import com.whfc.fuum.entity.SysRole;
import com.whfc.fuum.entity.SysUser;
import com.whfc.fuum.param.SysRoleAdd;
import com.whfc.fuum.param.SysRoleEdit;
import com.whfc.fuum.param.SysRoleRuleEdit;
import com.whfc.fuum.redis.SysUserRedisDao;
import com.whfc.fuum.service.SysRoleService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@DubboService(interfaceClass = SysRoleService.class, version = "1.0.0")
public class SysRoleServiceImpl implements SysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysRoleRuleMapper sysRoleRuleMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private SysDeptUserMapper sysDeptUserMapper;

    @Autowired
    private SysUserRedisDao sysUserRedisDao;

    @Override
    public List<SysRoleDTO> list(Integer userId, Integer deptId, String keyword) {
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(userId);
        if (sysUser == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "用户不存在.");
        }
        List<SysRoleDTO> list;

        List<Integer> deptIds = null;
        if (deptId != null) {
            deptIds = Collections.singletonList(deptId);
        }
        if (SysUserType.INNER.getValue().equals(sysUser.getType())) {
            //内部账号能看到所有的角色
            list = sysRoleMapper.selectRoleList(deptIds, keyword);
        } else {
            //普通用户可以看到自己所在的组织机构的角色
            if (deptId == null) {
                //如果组织机构为空 获取用户的所有组织机构
                deptIds = sysDeptUserMapper.selectDeptIdByUserId(userId);
            }
            //获取用户所属组织机构的所有角色
            list = sysRoleMapper.selectRoleList(deptIds, keyword);
        }
        return list;
    }

    /**
     * 添加角色
     */
    @Override
    public void add(SysRoleAdd request) {
        String roleName = request.getName();
        Integer deptId = request.getDeptId();
        SysRole role = sysRoleMapper.selectByNameAndDept(roleName, deptId);
        if (role != null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该角色名称已存在");
        }
        //添加角色
        SysRole sysRole = new SysRole();
        sysRole.setName(roleName);
        sysRole.setDeptId(deptId);
        sysRole.setCreateBy(request.getCreateBy());
        sysRole.setDescription(request.getDescription());
        sysRoleMapper.insertSelective(sysRole);
    }


    /**
     * 删除角色
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void del(Integer id) {
        int cnt = sysUserRoleMapper.countByRoleId(id);
        if (cnt > 0) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该角色下有账号不可删除!");
        }

        //删除相关用户的权限缓存
        clearRuleCache(id);

        //删除角色权限
        sysRoleRuleMapper.deleteByRoleId(id);
        //删除角色
        sysRoleMapper.deleteByPrimaryKey(id);

    }


    /**
     * 编辑角色
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(SysRoleEdit request) {
        Integer roleId = request.getId();
        SysRole sysRole = sysRoleMapper.selectByPrimaryKey(roleId);
        if (sysRole == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该角色不存在");
        }
        String roleName = request.getName();
        Integer deptId = request.getDeptId();
        SysRole role = sysRoleMapper.selectByNameAndDept(roleName, deptId);
        if (role != null && !role.getId().equals(sysRole.getId())) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该角色名称已存在");
        }

        sysRole.setId(roleId);
        sysRole.setDeptId(deptId);
        sysRole.setName(request.getName());
        sysRole.setDescription(request.getDescription());
        sysRoleMapper.updateByPrimaryKeySelective(sysRole);

        //删除相关用户的权限缓存
        clearRuleCache(roleId);
    }


    /**
     * 获得角色详情
     */
    @Override
    public SysRoleDetailDTO getRoleDetailById(Integer roleId, Integer platform) {
        SysRole role = sysRoleMapper.selectByPrimaryKey(roleId);
        if (role == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "角色不存在");
        }
        SysRulePlatform rulePlatform = SysRulePlatform.parseValue(platform);
        if (rulePlatform == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "权限平台不存在");
        }
        List<SysRuleDTO> ruleList = sysRoleRuleMapper.selectRuleDTOByRoleId(roleId, platform);
        SysRoleDetailDTO detailDTO = new SysRoleDetailDTO();
        detailDTO.setId(roleId);
        detailDTO.setDeptId(role.getDeptId());
        detailDTO.setName(role.getName());
        detailDTO.setRules(ruleList);
        return detailDTO;
    }

    @Override
    public List<SysUserDTO> getRoleUserList(Integer roleId) {
        return sysUserRoleMapper.selectUserListByRoleId(roleId);
    }

    @Override
    public List<SysRuleDTO> getRoleRuleList(Integer roleId, Integer platform) {
        SysRulePlatform rulePlatform = SysRulePlatform.parseValue(platform);
        if (rulePlatform == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "权限平台不存在");
        }
        return sysRoleRuleMapper.selectRuleDTOByRoleId(roleId, platform);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editRoleRule(SysRoleRuleEdit roleRuleEdit) {
        Integer roleId = roleRuleEdit.getRoleId();
        List<Integer> ruleIds = roleRuleEdit.getRuleIds();
        //先删除再添加
        sysRoleRuleMapper.deleteByRoleIdAndRulePlatform(roleId, roleRuleEdit.getPlatform());
        //添加角色权限
        if (!ruleIds.isEmpty()) {
            sysRoleRuleMapper.batchInsert(roleId, ruleIds);
        }

        //删除相关用户的权限缓存
        clearRuleCache(roleId);
    }

    @Override
    public List<SysUserDTO> selectUserByRoleIdsAndDeptId(Integer deptId, List<Integer> roleIds) throws BizException {
        if (roleIds == null || roleIds.isEmpty()) {
            return Collections.emptyList();
        }
        return sysUserRoleMapper.selectUserListByRoleIdsAndDeptId(deptId, roleIds);
    }

    /**
     * 清理用户权限缓存
     *
     * @param roleId 角色ID
     */
    private void clearRuleCache(Integer roleId) {
        List<Integer> userIds = sysUserRoleMapper.selectUserIdByRoleIds(Collections.singletonList(roleId));
        if (userIds.isEmpty()) {
            return;
        }
        sysUserRedisDao.deleteUserRules(userIds);
        //清理内部账号的权限缓存
        clearInnerRuleCache();
    }

    /**
     * 清理内部账号的权限缓存
     */
    private void clearInnerRuleCache() {
        //清理内部账号的权限缓存
        List<SysUserDTO> list = sysUserMapper.selectInnerUsers(null);
        List<Integer> userIdList = list.stream().map(SysUserDTO::getId).collect(Collectors.toList());
        sysUserRedisDao.deleteUserRules(userIdList);
    }
}
